Spring ORM এবং Multi-tenant Architecture

Java Technologies - স্প্রিং ওআরএম (Spring ORM)
105
105

Multi-tenant Architecture হল এমন একটি আর্কিটেকচার ডিজাইন, যেখানে একটি অ্যাপ্লিকেশন একাধিক গ্রাহক বা tenant-দের সমর্থন করে। এখানে, tenant বলতে একাধিক আলাদা কাস্টমার বা সংস্থাকে বোঝানো হয়, যাদের প্রতিটির জন্য আলাদা ডেটা, কনফিগারেশন এবং রিসোর্স থাকে। স্প্রিং ORM এর মাধ্যমে Multi-tenant Architecture বাস্তবায়ন করা সম্ভব, যেখানে Spring Data JPA বা Hibernate ব্যবহৃত হয় ডেটাবেস পরিচালনার জন্য।


Multi-tenant Architecture এবং তার প্রয়োজনীয়তা

Multi-tenant Architecture এর বৈশিষ্ট্য

  • Shared Database: সব tenant একই ডেটাবেস শেয়ার করে, তবে প্রতিটির ডেটা আলাদাভাবে সংরক্ষিত হয়।
  • Separate Database: প্রতিটি tenant এর জন্য আলাদা ডেটাবেস তৈরি করা হয়।
  • Hybrid Approach: কিছু ডেটা শেয়ার করা হয়, কিছু tenant এর জন্য আলাদা থাকে।

এটি সাধারণত SaaS (Software as a Service) অ্যাপ্লিকেশনগুলিতে ব্যবহৃত হয়, যেখানে একাধিক গ্রাহক একই অ্যাপ্লিকেশন ব্যবহারের পাশাপাশি তাদের নিজস্ব ডেটা নিরাপদ ও পৃথকভাবে রাখতে চান।


Spring ORM এবং Multi-tenant Architecture

Spring ORM ব্যবহারের মাধ্যমে Multi-tenant Architecture তৈরি করা হলে, Hibernate বা JPA এর সাহায্যে tenant এর ডেটা আলাদা করা হয়। এর জন্য বিভিন্ন স্ট্র্যাটেজি ব্যবহার করা যেতে পারে:

  • Database per Tenant: প্রতিটি tenant এর জন্য একটি আলাদা ডেটাবেস।
  • Schema per Tenant: এক ডেটাবেসের মধ্যে আলাদা স্কিমা ব্যবহার করা হয়।
  • Table per Tenant: একটিমাত্র টেবিল ব্যবহার করা হয়, যেখানে tenant নির্ধারিত কলাম দ্বারা আলাদা হয়।

Multi-tenant Architecture তৈরি করার পদ্ধতি

1. Database per Tenant Approach

এই পদ্ধতিতে প্রতিটি tenant এর জন্য একটি পৃথক ডেটাবেস থাকে। স্প্রিং ORM ব্যবহার করে ডেটাবেস ডাইনামিকভাবে নির্বাচিত করা হয় tenant এর ভিত্তিতে।

DataSource Configuration

@Configuration
public class DataSourceConfig {

    @Bean
    @Primary
    public DataSource dataSource() {
        AbstractRoutingDataSource dataSource = new AbstractRoutingDataSource() {
            @Override
            protected Object determineCurrentLookupKey() {
                return TenantContext.getCurrentTenant();
            }
        };
        
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("tenant1", tenant1DataSource());
        targetDataSources.put("tenant2", tenant2DataSource());
        dataSource.setTargetDataSources(targetDataSources);
        
        return dataSource;
    }

    private DataSource tenant1DataSource() {
        // Configure tenant 1 DataSource
    }

    private DataSource tenant2DataSource() {
        // Configure tenant 2 DataSource
    }
}

TenantContext ব্যবহার

প্রতিটি HTTP রিকোয়েস্টে tenant নির্বাচন করতে TenantContext ক্লাস ব্যবহার করা হয়।

public class TenantContext {

    private static final ThreadLocal<String> currentTenant = new ThreadLocal<>();

    public static void setCurrentTenant(String tenant) {
        currentTenant.set(tenant);
    }

    public static String getCurrentTenant() {
        return currentTenant.get();
    }

    public static void clear() {
        currentTenant.remove();
    }
}

এইভাবে, প্রতিটি রিকোয়েস্টে ডেটাবেস নির্ধারণ করা হয়, এবং tenant এর ভিত্তিতে ডেটাবেস নির্বাচন করা হয়।


2. Schema per Tenant Approach

এই পদ্ধতিতে একক ডেটাবেসের মধ্যে আলাদা স্কিমা ব্যবহার করা হয়। প্রতিটি tenant এর জন্য আলাদা স্কিমা তৈরি করা হয় এবং ডেটাবেস লেয়ারের স্কিমার মধ্যে পার্থক্য তৈরি করা হয়।

SchemaRoutingDataSource কনফিগারেশন

@Configuration
public class DataSourceConfig {

    @Bean
    @Primary
    public DataSource dataSource() {
        AbstractRoutingDataSource dataSource = new AbstractRoutingDataSource() {
            @Override
            protected Object determineCurrentLookupKey() {
                return TenantContext.getCurrentTenant();
            }
        };

        // Map of schemas based on tenant
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("tenant1", tenant1DataSource());
        targetDataSources.put("tenant2", tenant2DataSource());
        dataSource.setTargetDataSources(targetDataSources);

        return dataSource;
    }

    private DataSource tenant1DataSource() {
        // Configure schema for tenant 1
    }

    private DataSource tenant2DataSource() {
        // Configure schema for tenant 2
    }
}

এখানে, schema-based multi-tenancy ব্যবহৃত হয়েছে, যেখানে tenant এর ভিত্তিতে আলাদা স্কিমা নির্বাচন করা হয়।


3. Table per Tenant Approach

এই পদ্ধতিতে একাধিক টেবিল তৈরি করা হয়, যেখানে প্রতিটি tenant এর জন্য একটি আলাদা টেবিল থাকে। সাধারণত এটি কম ব্যবহৃত হয় কারণ এটি অধিক টেবিল তৈরি করে এবং পরিচালনা করতে জটিল হতে পারে।

Entity Design

@Entity
@Table(name = "employee_tenant1")
public class EmployeeTenant1 {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String department;

    // Getters and Setters
}

এখানে, employee_tenant1 টেবিলটি tenant 1 এর জন্য এবং employee_tenant2 টেবিলটি tenant 2 এর জন্য আলাদা হবে।


Spring ORM এবং Multi-tenant Architecture ব্যবহারের সুবিধা

  1. ডেটার আলাদা সংরক্ষণ: প্রতিটি tenant এর ডেটা আলাদাভাবে সংরক্ষণ করা হয়, যা নিরাপত্তা এবং পারফর্মেন্সের জন্য উপকারী।
  2. ফ্লেক্সিবিলিটি: একাধিক ডেটাবেস বা স্কিমার মাধ্যমে tenant গুলোকে পৃথক করা যায়, এবং সিস্টেমের ফ্লেক্সিবিলিটি বৃদ্ধি পায়।
  3. প্রতিক্রিয়া ক্ষমতা বৃদ্ধি: Multi-tenant আর্কিটেকচারের মাধ্যমে একই অ্যাপ্লিকেশন দিয়ে অনেক গ্রাহককে সমর্থন করা যায়, যা ব্যবস্থাপনায় সহায়ক।

সারাংশ

স্প্রিং ORM এবং Multi-tenant Architecture ব্যবহার করে একাধিক গ্রাহক বা tenant গুলোর ডেটা নিরাপদভাবে এবং পৃথকভাবে সংরক্ষণ করা সম্ভব। তিনটি প্রধান পদ্ধতি (Database per Tenant, Schema per Tenant, Table per Tenant) ব্যবহার করে এটি বাস্তবায়ন করা যায়, যার প্রতিটির আলাদা সুবিধা ও চ্যালেঞ্জ রয়েছে। স্প্রিং ORM ব্যবহার করে Multi-tenant আর্কিটেকচার সহজেই বাস্তবায়ন করা সম্ভব, যা সিস্টেমের স্কেলেবিলিটি এবং নিরাপত্তা উন্নত করে।

Content added By

Multi-tenant Architecture কি এবং কেন এটি গুরুত্বপূর্ণ?

71
71

Multi-tenant Architecture হল একটি সফটওয়্যার আর্কিটেকচার যেখানে একটি একক অ্যাপ্লিকেশন বা ডাটাবেস পরিবেশ (Environment) একাধিক গ্রাহক (Tenant) বা ক্লায়েন্টের সেবা প্রদান করে। প্রতিটি টেন্যান্ট একটি পৃথক এবং আলাদা পরিবেশ অনুভব করলেও, সমস্ত টেন্যান্ট একই অ্যাপ্লিকেশন বা ডাটাবেস ইনস্ট্যান্সের মাধ্যমে সেবা নেয়। এটি বিশেষ করে SaaS (Software as a Service) মডেল ব্যবহৃত অ্যাপ্লিকেশনগুলোর মধ্যে ব্যবহৃত হয়।


Multi-tenant Architecture এর মূল ধারণা

একটি multi-tenant অ্যাপ্লিকেশন বা ডাটাবেসে, একাধিক টেন্যান্ট বা গ্রাহক একই ইনফ্রাস্ট্রাকচারে চলতে থাকে, তবে তাদের ডেটা, কনফিগারেশন এবং সংস্থান পৃথক এবং নিরাপদ থাকে। এতে প্রতিটি টেন্যান্ট অন্য টেন্যান্ট থেকে বিচ্ছিন্ন থাকে, যদিও তারা একই অ্যাপ্লিকেশন শেয়ার করে।


Multi-tenant Architecture এর ধরন

  1. Shared Database, Shared Schema
    সব টেন্যান্ট একই ডাটাবেস এবং স্কিমা শেয়ার করে। তবে, প্রতিটি টেন্যান্টের ডেটা আলাদা থাকে, সাধারণত tenant_id ব্যবহার করে পার্থক্য করা হয়।
  2. Shared Database, Separate Schema
    একই ডাটাবেস ব্যবহার করা হলেও, প্রতিটি টেন্যান্টের জন্য আলাদা স্কিমা থাকে। এটি টেন্যান্টদের মধ্যে আরও ভাল বিচ্ছিন্নতা (Isolation) প্রদান করে।
  3. Separate Database
    প্রতিটি টেন্যান্টের জন্য আলাদা ডাটাবেস ব্যবহার করা হয়। এই ধরণের আর্কিটেকচার সম্পূর্ণ বিচ্ছিন্নতা প্রদান করে, তবে এটি বেশি রিসোর্স এবং পরিচালনা খরচের প্রয়োজন হয়।

Multi-tenant Architecture কেন গুরুত্বপূর্ণ?

১. খরচ কমানো

Multi-tenant অ্যাপ্লিকেশনে একাধিক ক্লায়েন্ট একই অ্যাপ্লিকেশন, ডাটাবেস, এবং সার্ভার ব্যবহার করে, যা ইন্ডাস্ট্রি স্ট্যান্ডার্ড ডেটা ম্যানেজমেন্ট এবং সার্ভার রিসোর্স ব্যবহারের ক্ষেত্রে খরচ কমাতে সাহায্য করে।

২. স্কেলেবিলিটি (Scalability)

একই অ্যাপ্লিকেশন ব্যবহার করার ফলে নতুন টেন্যান্ট যোগ করা সহজ হয়। যখন আপনার অ্যাপ্লিকেশন একাধিক ক্লায়েন্ট হ্যান্ডেল করতে সক্ষম হয়, তখন এটি আরও স্কেলেবল হয়ে ওঠে। একক ইনস্ট্যান্স থেকে একাধিক গ্রাহকের সেবা প্রদান করা যায়, যা পারফরম্যান্সে কোনও প্রভাব ফেলে না।

৩. কেন্দ্রীয় মেইনটেন্যান্স (Centralized Maintenance)

Multi-tenant আর্কিটেকচারের মাধ্যমে সফটওয়্যার মেইনটেন্যান্স এবং আপডেট একাধিক ক্লায়েন্টের জন্য একসাথে করা সম্ভব। এতে ক্লায়েন্টদের একে একে আপডেট দেওয়ার ঝামেলা নেই, বরং একক ইনস্ট্যান্স থেকেই সমস্ত টেন্যান্টকে আপডেট করা যায়।

৪. সুবিধাজনক এবং দ্রুত ডেপ্লয়মেন্ট

একই অ্যাপ্লিকেশন এবং ডাটাবেসে একাধিক টেন্যান্ট থাকলে নতুন টেন্যান্ট যোগ করা সহজ হয়ে যায়। নতুন ক্লায়েন্টের জন্য নতুন ডাটাবেস বা সার্ভার স্থাপন করতে হয় না, ফলে দ্রুত এবং কার্যকরী ডেপ্লয়মেন্ট সম্ভব হয়।

৫. ডেটা বিচ্ছিন্নতা এবং নিরাপত্তা

প্রতিটি টেন্যান্টের ডেটা অন্য টেন্যান্ট থেকে সুরক্ষিত রাখা হয়। যদিও সমস্ত টেন্যান্ট একই ইনফ্রাস্ট্রাকচার ব্যবহার করে, তবে proper isolation এবং access control ব্যবস্থার মাধ্যমে ডেটার সুরক্ষা নিশ্চিত করা যায়।


Spring ORM এ Multi-tenant Architecture বাস্তবায়ন

Spring ORM-এ Multi-tenant অ্যাপ্লিকেশন তৈরি করার জন্য সাধারণত দুটি পদ্ধতি ব্যবহার করা হয়:

১. Database Routing

এই পদ্ধতিতে, tenant_id এর ভিত্তিতে Spring ORM ডাটাবেস রাউটিং করে, যাতে সঠিক টেন্যান্টের ডেটাবেসে কুয়েরি পাঠানো হয়। এটি সাধারণত AbstractRoutingDataSource ক্লাস ব্যবহার করে বাস্তবায়ন করা হয়।

public class MultiTenantDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return TenantContext.getCurrentTenant(); // tenant_id return করা হবে
    }
}

২. Hibernate Multi-tenant Configuration

Hibernate একটি MultiTenancyStrategy প্রদান করে, যার মাধ্যমে টেন্যান্টের জন্য আলাদা স্কিমা বা ডাটাবেস ব্যবহার করা যায়। এই কনফিগারেশন সাধারণত hibernate.multiTenancy প্রপার্টি দিয়ে করা হয়।

<property name="hibernate.multiTenancy" value="SCHEMA"/>
<property name="hibernate.tenant_identifier_resolver" value="com.example.TenantIdentifierResolver"/>
<property name="hibernate.multi_tenant_connection_provider" value="com.example.MultiTenantConnectionProvider"/>

Multi-tenant Architecture এর সুবিধা এবং চ্যালেঞ্জ

সুবিধা:

  • কেন্দ্রীয় মেইনটেন্যান্স এবং স্কেলেবিলিটি.
  • খরচ সাশ্রয়ী এবং ডেপ্লয়মেন্টে সুবিধা.
  • একই সফটওয়্যার সিস্টেমের মধ্যে একাধিক ক্লায়েন্ট পরিচালনার সহজ উপায়।
  • উন্নত ডেটা সুরক্ষা এবং প্রাইভেসি

চ্যালেঞ্জ:

  • ডেটা বিচ্ছিন্নতা বজায় রাখা কঠিন হতে পারে।
  • প্রাথমিক কনফিগারেশন এবং সঠিকভাবে রাউটিং ব্যবস্থার প্রয়োজন।
  • ডাটাবেস স্কিমা বা সার্ভার সংস্থান যথাযথভাবে পরিচালনা করা প্রয়োজন।
  • সিস্টেমের কার্যকারিতা এবং পারফরম্যান্স পর্যাপ্তভাবে নিশ্চিত করা।

সারাংশ

Multi-tenant Architecture একটি শক্তিশালী আর্কিটেকচার প্যাটার্ন যা একাধিক ক্লায়েন্টের জন্য একটি একক অ্যাপ্লিকেশন বা ডাটাবেস ব্যবস্থাপনা করে। এটি খরচ কমানো, স্কেলেবিলিটি উন্নত করা, এবং কেন্দ্রীকৃত মেইনটেন্যান্স সহজ করে। তবে, এটি কিছু চ্যালেঞ্জের মুখোমুখি হয়, যেমন ডেটা বিচ্ছিন্নতা এবং পারফরম্যান্স অপটিমাইজেশন। Spring ORM-এ Multi-tenant অ্যাপ্লিকেশন ব্যবহারে Database Routing এবং Hibernate Multi-tenant Configuration ব্যবহৃত হতে পারে, যা ডাটাবেস রাউটিং এবং টেন্যান্ট আইডেন্টিফিকেশন সঠিকভাবে পরিচালনা করতে সাহায্য করে।

Content added By

Spring এবং Hibernate ব্যবহার করে Multi-tenancy বাস্তবায়ন

79
79

Multi-tenancy একটি প্রযুক্তিগত কৌশল যা একাধিক গ্রাহক বা "tenant"-কে একটি একক অ্যাপ্লিকেশন বা ডাটাবেসে পরিষেবা সরবরাহ করার জন্য ব্যবহৃত হয়। এটি মূলত ব্যবহৃত হয় SaaS (Software as a Service) অ্যাপ্লিকেশনগুলিতে, যেখানে একাধিক গ্রাহক একি অ্যাপ্লিকেশন ব্যবহার করে কিন্তু তাদের ডেটা একে অপর থেকে পৃথক থাকে।

Hibernate এবং Spring ORM ব্যবহার করে Multi-tenancy বাস্তবায়ন করা সম্ভব, যেখানে বিভিন্ন tenant এর জন্য আলাদা আলাদা ডাটাবেস অথবা স্কিমা ব্যবহার করা যেতে পারে।


Multi-tenancy এর ধরন

  1. ডাটাবেস পার্টিশন (Database Partitioning): আলাদা ডাটাবেস ব্যবহার করা হয়, যেখানে প্রতিটি tenant এর জন্য আলাদা ডাটাবেস থাকে।
  2. স্কিমা পার্টিশন (Schema Partitioning): এক ডাটাবেস ব্যবহার হয়, কিন্তু প্রতিটি tenant এর জন্য আলাদা স্কিমা রাখা হয়।
  3. টেবিল পার্টিশন (Table Partitioning): এক স্কিমা এবং এক টেবিল ব্যবহার করা হয়, তবে tenant_id দিয়ে ডাটা আলাদা করা হয়।

Maven ডিপেনডেন্সি

Spring ORM এবং Hibernate ব্যবহার করতে নিচের ডিপেনডেন্সি যোগ করুন:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.5.4</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.26</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.6.1.Final</version>
</dependency>

Multi-tenancy কনফিগারেশন

Hibernate এর সাথে Multi-tenancy কনফিগার করতে আপনাকে কিছু নির্দিষ্ট কনফিগারেশন করতে হবে। নিম্নলিখিত পদক্ষেপে Multi-tenancy কনফিগারেশন বাস্তবায়ন করা হবে।

Step 1: Hibernate Multi-tenancy কনফিগারেশন

Hibernate এর Multi-tenancy সমর্থন করতে নিচের কনফিগারেশন ফাইলটি ব্যবহার করা হয়:

hibernate.multiTenancy=SCHEMA
hibernate.tenant_identifier_resolver=com.example.MultiTenantIdentifierResolver
hibernate.multi_tenant_connection_provider=com.example.MultiTenantConnectionProviderImpl
hibernate.hbm2ddl.auto=update

Step 2: Tenant Identifier Resolver তৈরি করা

Hibernate কে tenant কে চিনতে সাহায্য করতে একটি TenantIdentifierResolver ইন্টারফেস ইমপ্লিমেন্ট করতে হবে। এখানে আমরা TenantContext থেকে tenant আইডি সংগ্রহ করছি।

public class MultiTenantIdentifierResolver implements CurrentTenantIdentifierResolver {

    @Override
    public String resolveCurrentTenantIdentifier() {
        String tenantId = TenantContext.getTenantId();
        if (tenantId == null) {
            tenantId = "default_tenant";  // default tenant
        }
        return tenantId;
    }

    @Override
    public boolean validateExistingCurrentSessions() {
        return true;
    }
}

Step 3: Multi-Tenant Connection Provider তৈরি করা

এই ক্লাসটি Hibernate কে ডাটাবেস কানেকশন প্রদান করবে। এখানে আমরা প্রতিটি tenant এর জন্য আলাদা ডাটাবেস কানেকশন প্রদান করছি।

public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider {

    private DataSource dataSource;

    @Autowired
    public MultiTenantConnectionProviderImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public Connection getAnyConnection() throws SQLException {
        return dataSource.getConnection();
    }

    @Override
    public Connection getConnection(String tenantIdentifier) throws SQLException {
        // Tenant-specific DataSource logic
        // You could configure different databases per tenant
        return dataSource.getConnection();
    }

    @Override
    public boolean supportsAggressiveRelease() {
        return false;
    }

    @Override
    public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
        connection.close();
    }
}

Entity ক্লাস

Entity ক্লাসের মধ্যে আপনি সাধারণত @Entity অ্যানোটেশন ব্যবহার করেন। Multi-tenancy ব্যবস্থাপনার জন্য কোন অতিরিক্ত অ্যানোটেশন প্রয়োজন হয় না, তবে @Table এর মাধ্যমে প্রতিটি tenant এর জন্য আলাদা টেবিল বা স্কিমা ব্যবহার করতে হবে।

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String email;

    // Getters and Setters
}

Tenant Context তৈরি করা

Tenant তথ্য স্টোর করার জন্য একটি TenantContext ক্লাস তৈরি করা যেতে পারে, যা টেন্যান্ট আইডি পরিচালনা করবে।

public class TenantContext {
    private static final ThreadLocal<String> tenantContext = new ThreadLocal<>();

    public static void setTenantId(String tenantId) {
        tenantContext.set(tenantId);
    }

    public static String getTenantId() {
        return tenantContext.get();
    }

    public static void clear() {
        tenantContext.remove();
    }
}

Spring Configuration Class

এটি Spring কনফিগারেশন ক্লাস যা Hibernate এর Multi-tenancy কনফিগারেশন এবং DataSource সাপোর্ট প্রদান করে।

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.example.repository")
public class JpaConfig {

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean factoryBean = builder
                .dataSource(dataSource)
                .packages("com.example.entity")
                .persistenceUnit("multiTenantPU")
                .properties(hibernateProperties())
                .build();

        return factoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.multiTenancy", "SCHEMA");
        properties.put("hibernate.tenant_identifier_resolver", "com.example.MultiTenantIdentifierResolver");
        properties.put("hibernate.multi_tenant_connection_provider", "com.example.MultiTenantConnectionProviderImpl");
        return properties;
    }
}

Service Layer

এখন আমরা সার্ভিস লেয়ার তৈরি করতে পারি, যেখানে আমরা tenant-specific ডেটা পরিচালনা করব।

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public User saveUser(User user) {
        return userRepository.save(user);
    }

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
}

Controller Layer

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/add")
    public ResponseEntity<User> addUser(@RequestBody User user) {
        userService.saveUser(user);
        return ResponseEntity.ok(user);
    }

    @GetMapping("/all")
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }
}

Multi-tenancy এর সুবিধা

  1. ডেটা আলাদা রাখা: প্রতিটি tenant এর ডেটা আলাদাভাবে সংরক্ষিত থাকে, ফলে নিরাপত্তা নিশ্চিত করা হয়।
  2. কোড রি-ইউজ: একটিমাত্র অ্যাপ্লিকেশন কোড একাধিক tenant এর জন্য ব্যবহৃত হতে পারে।
  3. স্কেলেবিলিটি: নতুন tenant যোগ করা বা পুরানো tenant অপসারণ করা সহজ।

Spring এবং Hibernate ব্যবহার করে Multi-tenancy বাস্তবায়ন, একাধিক tenant এর জন্য আলাদা ডাটাবেস বা স্কিমা পরিচালনা করে সিস্টেমের পারফরম্যান্স এবং সিকিউরিটি বৃদ্ধি করতে সাহায্য করে।

Content added By

উদাহরণ সহ Multi-tenant ORM কনফিগারেশন

58
58

মাল্টি-টেনেন্সি (Multi-Tenancy) কী?

মাল্টি-টেনেন্সি (Multi-Tenancy) হলো একটি অ্যাপ্লিকেশন বা ডাটাবেস আর্কিটেকচার যা একক ইনস্ট্যান্স ব্যবহার করে একাধিক ক্লায়েন্ট বা "টেনেন্ট" (tenant) এর তথ্য সংগ্রহ এবং পরিচালনা করে। স্প্রিং ORM এবং Hibernate ব্যবহার করে মাল্টি-টেনেন্সি বাস্তবায়ন করলে, একাধিক ডাটাবেস বা একক ডাটাবেসে বিভিন্ন টেবিলের মাধ্যমে ডেটা আলাদা করা যায়।

এটি সাধারণত ডাটাবেস পার্টিশনিং (Database Partitioning), টেবিল পার্টিশনিং (Table Partitioning) বা একাধিক ডাটাবেস (Multiple Databases) এর মাধ্যমে করা হয়। মাল্টি-টেনেন্ট কনফিগারেশন বেশিরভাগ ক্ষেত্রে একটি অ্যাপ্লিকেশনে একাধিক টেনেন্টের জন্য আলাদা ডেটা রাখতে ব্যবহৃত হয়, যেমন ক্লাউড ভিত্তিক অ্যাপ্লিকেশন যেখানে বিভিন্ন ক্লায়েন্টের ডেটা পৃথক রাখতে হয়।


স্প্রিং ORM এ মাল্টি-টেনেন্ট কনফিগারেশন উদাহরণ

স্প্রিং ORM এর মাধ্যমে মাল্টি-টেনেন্ট কনফিগারেশন কিভাবে করবেন তা উদাহরণসহ আলোচনা করা হলো। এখানে Database per Tenant পদ্ধতি অনুসরণ করা হবে, যেখানে প্রতিটি টেনেন্টের জন্য আলাদা ডাটাবেস থাকবে।


1. ডাটাবেস কনফিগারেশন

প্রথমে একটি DataSource কনফিগারেশন তৈরি করতে হবে, যা ডাটাবেসের সংযোগ পরিচালনা করবে। এখানে আমরা AbstractRoutingDataSource ব্যবহার করবো যা ডাটাবেস নির্বাচনের জন্য নির্দিষ্ট কন্টেক্সট অনুসারে ডাইনামিক্যালি ডাটাবেস নির্বাচন করবে।

MultiTenantDataSource ক্লাস

package com.example.config;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class MultiTenantDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return TenantContext.getCurrentTenant(); // ডাইনামিক্যালি টেনেন্ট নির্বাচন
    }
}

2. TenantContext ক্লাস

TenantContext ক্লাসটি থ্রেড-লোকাল কন্টেক্সট ব্যবহার করে বর্তমানে যে টেনেন্ট সক্রিয় রয়েছে সেটি সংরক্ষণ করবে।

package com.example.config;

public class TenantContext {
    private static final ThreadLocal<String> currentTenant = new ThreadLocal<>();

    public static void setCurrentTenant(String tenant) {
        currentTenant.set(tenant);
    }

    public static String getCurrentTenant() {
        return currentTenant.get();
    }

    public static void clear() {
        currentTenant.remove();
    }
}

3. ডাটাবেস কনফিগারেশন ফাইল (applicationContext.xml)

Spring কনফিগারেশন ফাইলে MultiTenantDataSource কনফিগারেশন এবং টেনেন্টের জন্য ডাটা সোর্স সংজ্ঞায়িত করা হবে।

<bean id="dataSource" class="com.example.config.MultiTenantDataSource">
    <property name="targetDataSources">
        <map>
            <entry key="tenant1" value-ref="tenant1DataSource"/>
            <entry key="tenant2" value-ref="tenant2DataSource"/>
        </map>
    </property>
    <property name="defaultTargetDataSource" ref="tenant1DataSource"/>
</bean>

<bean id="tenant1DataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/tenant1_db"/>
    <property name="username" value="root"/>
    <property name="password" value="password"/>
</bean>

<bean id="tenant2DataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/tenant2_db"/>
    <property name="username" value="root"/>
    <property name="password" value="password"/>
</bean>

4. Hibernate SessionFactory কনফিগারেশন

Hibernate SessionFactory কনফিগারেশন টেনেন্ট ডেটাবেস অনুযায়ী ডাইনামিক্যালি কনফিগার করা হবে।

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="com.example.model"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
</bean>

5. Service Layer

TenantContext ব্যবহার করে সঠিক টেনেন্ট নির্বাচিত করে তার জন্য ডাটাবেস সংযোগ করা হবে।

package com.example.service;

import com.example.config.TenantContext;
import com.example.dao.UserDao;
import com.example.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public User getUser(int id, String tenant) {
        TenantContext.setCurrentTenant(tenant); // টেনেন্ট নির্বাচিত
        return userDao.getUser(id);
    }
}

6. DAO Layer

DAO লেয়ারটি SessionFactory থেকে সেশন নেবে এবং সঠিক ডাটাবেসের সঙ্গে কাজ করবে।

package com.example.dao;

import com.example.model.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class UserDao {

    @Autowired
    private SessionFactory sessionFactory;

    public User getUser(int id) {
        Session session = sessionFactory.getCurrentSession();
        return session.get(User.class, id);
    }
}

7. Controller Layer

কন্ট্রোলার লেয়ারটি UserService থেকে ডাটা ফেচ করবে এবং টেনেন্টের ভিত্তিতে ডাটাবেস নির্বাচন করবে।

package com.example.controller;

import com.example.model.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/{tenant}/{id}")
    public User getUser(@PathVariable String tenant, @PathVariable int id) {
        return userService.getUser(id, tenant);
    }
}

সারাংশ

স্প্রিং ORM এ মাল্টি-টেনেন্ট কনফিগারেশনটি একটি শক্তিশালী পদ্ধতি, যা একাধিক টেনেন্টের ডেটা নিরাপদভাবে এবং পৃথকভাবে পরিচালনা করতে সহায়ক। AbstractRoutingDataSource ব্যবহার করে ডাটাবেস ডাইনামিক্যালি নির্বাচন করা এবং TenantContext এর মাধ্যমে টেনেন্টের কন্টেক্সট ট্র্যাক করা হয়। এই কনফিগারেশনের মাধ্যমে একাধিক টেনেন্টের জন্য একটি কনসোলিডেটেড ডেটাবেস স্ট্রাকচার তৈরি করা যায়।

Content added By
টপ রেটেড অ্যাপ

স্যাট অ্যাকাডেমী অ্যাপ

আমাদের অল-ইন-ওয়ান মোবাইল অ্যাপের মাধ্যমে সীমাহীন শেখার সুযোগ উপভোগ করুন।

ভিডিও
লাইভ ক্লাস
এক্সাম
ডাউনলোড করুন
Promotion